package nz.net.pole.util;

/**
 * An abstract class which allows subclasses that have an identity (ID) number and a name associated to it. Since many
 * classes have an identity and name for its instances &mdash; it makes sense to have a generic superclass implementing
 * methods for dealing with the identity and name of an object instance. This allows, for example, the creation of
 * classes to deal with collections of objects that have an identity and name.
 * 
 * @author James Pole (james@pole.net.nz)
 */
public abstract class IdentityNameObject {

    /**
     * Minimum length of names.
     */
    private static final int NAME_LENGTH_MIN = 1;
    /**
     * Maximum length of names.
     */
    private static final int NAME_LENGTH_MAX = 255;
    /**
     * The identity of this instance.
     */
    private int identity;
    /**
     * The name of this instance.
     */
    private String name;

    /**
     * Creates an instance with the given identity and name.
     * 
     * @param identity The proposed identity of this instance.
     * @param name The proposed name of this instance.
     */
    public IdentityNameObject(int identity, String name) {

        setIdentity(identity);
        setName(name);

    }

    /**
     * Returns the identity of this instance.
     * @return The identity of this instance.
     */
    public int getIdentity() {

        return (identity);

    }

    /**
     * Returns the name of this instance.
     * @return The name of this instance.
     */
    public String getName() {

        return (name);

    }

    /**
     * Sets the identity of this instance to the given identity. The given identity must be a postitive non-zero number
     * (i.e. one or greater).
     * 
     * @param identity The proposed identity of this instance.
     * @throws IllegalIdentityException If <code>identity</code> was zero or less than zero.
     */
    public void setIdentity(int identity) {

        if (identity <= 0) {

            throw new IllegalIdentityException(identity);

        }

        this.identity = identity;

    }

    /**
     * Sets the name of this instance to the given name. The given name must be a string with between 1 to 255
     * characters (inclusive).
     * 
     * @param name The proposed name of this instance.
     * @throws IllegalNameException If <code>name</code> was less than 1 character or more than 255 characters in
     *                              length.
     * @throws NullArgumentException If <code>name</code> was a null pointer.
     */
    public void setName(String name) {

        if (name == null) {

            throw new NullArgumentException("name");

        } else if (name.length() < NAME_LENGTH_MIN || name.length() > NAME_LENGTH_MAX) {

            throw new IllegalNameException(name, NAME_LENGTH_MIN, NAME_LENGTH_MAX);

        }

        this.name = name;

    }

    /**
     * Returns the output of <code>getName()</code>.
     * @return The output of {@link #getName()}.
     */
    public final String toString() {

        return (getName());

    }
}
